<?php

namespace app\common\util;

/** 腾讯 无服务器云函数接口调用 */
class TcScfUtil
{
    private $secretId;
    private $secretKey;
    private $region = "";               // 地域
    private $service = "billing";                       // 产品服务名
    private $host = "billing.tencentcloudapi.com";      // 产品默认域名
    private $timestamp;
    private $date;
    private $version = "2018-07-09";                // api版本号
    private $signatureMethod = "TC3-HMAC-SHA256";   // 签名方法
    private $httpRequestMethod = "POST";            // 请求类型
    private $canonicalUri = "/";
    private $signedHeaders = "content-type;host";
    private $canonicalHeaders;
    private $url = "https://billing.tencentcloudapi.com";// 请求地址
    private $returnData;

    public function __construct($secretId, $secretKey)
    {
        $this->secretId = $secretId;
        $this->secretKey = $secretKey;
        $this->canonicalHeaders = "content-type:application/json\nhost:{$this->host}\n";
    }

    // 请求接口的签名准备过程
    public function preSignPrepare($data){
        $this->timestamp = time();
        $this->date = date("Y-m-d", $this->timestamp);

        // ************* 步骤 1：拼接规范请求串 *************
        $hashedRequestPayload = strtolower(bin2hex(hash("sha256", $data, true)));
        $canonicalRequest = "{$this->httpRequestMethod}\n{$this->canonicalUri}\n\n{$this->canonicalHeaders}\n{$this->signedHeaders}\n{$hashedRequestPayload}";

        // ************* 步骤 2：拼接待签名字符串 *************
        $credentialScope = "{$this->date}/{$this->service}/tc3_request";
        $hashedCanonicalRequest = strtolower(bin2hex(hash("sha256", $canonicalRequest, true)));
        $stringToSign = "{$this->signatureMethod}\n{$this->timestamp}\n{$credentialScope}\n{$hashedCanonicalRequest}";

        // ************* 步骤 3：计算签名 *************
        $secretDate = hash_hmac('sha256', $this->date, "TC3".$this->secretKey, true);
        $secretService = hash_hmac('sha256', $this->service, $secretDate, true);
        $secretSigning = hash_hmac('sha256', "tc3_request", $secretService, true);
        $signature = strtolower(bin2hex((hash_hmac('sha256', $stringToSign, $secretSigning, true))));
        $authorization = "{$this->signatureMethod} Credential={$this->secretId}/{$credentialScope}, SignedHeaders={$this->signedHeaders}, Signature={$signature}";

        return $authorization;
    }

    // 请求接口返回结果
    public function getRequest($action, $data){
        $requestData = json_encode($data, JSON_UNESCAPED_UNICODE|JSON_FORCE_OBJECT);
        // 组装请求头
        $header[] = "Authorization:".$this->preSignPrepare($requestData);
        $header[] = "Host:{$this->host}";
        $header[] = "Content-Type:application/json";
        $header[] = "X-TC-Action:{$action}";
        $header[] = "X-TC-Timestamp:{$this->timestamp}";
        $header[] = "X-TC-Version:{$this->version}";
        $header[] = "X-TC-Region:{$this->region}";

        $res = json_decode(Tools::curl($this->url, $requestData, $header, 300),true);
        if(isset($res["Response"]["Error"])){
            $this->returnData = ErrorCode::code("fail");
            $this->returnData["msg"] = $res["Response"]["Error"]["Message"];
            $this->returnData["error"] = $res["Response"]["Error"];
            if(isset($data["Code"])){
                unset($data["Code"]);
            }
            unset($data["ZipFile"], $data["Code"]); // 删除文件流，为了记录日志文件不会很大
            Tools::writeLog(__METHOD__."--腾讯云云函数出错：".var_export($res,1).var_export($data,1), "{$action}.txt");
        }else{
            $this->returnData = ErrorCode::code("success");
            $this->returnData["data"] = isset($res["Response"]) ? $res["Response"] : $res;
        }
        return $this->returnData;
    }

    // 获取账户余额
    public function describeAccountBalance(){
        $action = "DescribeAccountBalance"; // 创建云函数的接口名
        return $this->getRequest($action, []);
    }
}